package com.example.demo.leetcode100题;

import com.example.demo.StopWatchTemplate;

/**
 * @author：zzc
 * @date: 2022/9/1
 */
public class 环形链表2 {

    //给定一个链表，返回链表开始入环的第一个节点。如果链表无环，则返回 null。
    //为了表示给定链表中的环，我们使用整数 pos 来表示链表尾连接到链表中
    //的位置（索引从 0 开始）。 如果 pos 是 -1，则在该链表中没有环。注意，pos
    //仅仅是用于标识环的情况，并不会作为参数传递到函数中。
    //说明：不允许修改给定的链表。
    //进阶：你是否可以使用 O(1) 空间解决此题？

    public static void main(String[] args) {
        ListNode node1 = new ListNode(1);
        node1.next = new ListNode(2);
        node1.next.next = new ListNode(2);
        node1.next.next.next = new ListNode(1);
        System.out.println(StopWatchTemplate.doSupplier(() -> hasCycle(node1)));
    }

    private static ListNode hasCycle(ListNode head) {
        if (head == null) {
            return null;
        }
        boolean loopExists = false;
        ListNode slowPtr = head, fastPtr = head;
        while (fastPtr.next != null && fastPtr.next.next != null) {
            slowPtr = slowPtr.next;
            fastPtr = fastPtr.next.next;
            if (slowPtr == fastPtr) {
                loopExists = true;
                break;
            }
        }
        // 环存在  快指针变成只移动一次
        if (loopExists) {
            slowPtr = head;
            while (slowPtr != fastPtr) {
                fastPtr = fastPtr.next;
                slowPtr = slowPtr.next;
            }
            return slowPtr;
        }
        return null;
    }

}
